<?php

namespace Xin\LaravelFortify\Foundation\Http;

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest as BaseFormRequest;
use Xin\LaravelFortify\Validation\ValidationException;

class FormRequest extends BaseFormRequest
{
    /**
     * 表示验证器是否应在第一个规则失败时停止。
     *
     * @var bool
     */
    protected $stopOnFirstFailure = true;

    /**
     * @var array
     */
    protected $rules = [];

    /**
     * @var array
     */
    protected $messages = [];

    /**
     * @var array
     */
    protected $fields = [];

    /**
     * 获取验证器的自定义规则。
     *
     * @return array
     */
    public function rules()
    {
        $commonRules = property_exists($this, 'rule') ? $this->rule : $this->rules;
        $commonRules = array_merge($commonRules, $this->commonRules());

        if ($this->isCreateScene()) {
            $commonRules = array_merge($commonRules, $this->createRules());
        } elseif ($this->isUpdateScene()) {
            $commonRules = array_merge($commonRules, $this->updateRules());
        } else {
            $scene = $this->getScene();
            $sceneMethod = $scene . 'Rules';
            if (method_exists($this, $sceneMethod)) {
                $commonRules = array_merge($commonRules, $this->$sceneMethod());
            }
        }

        return $commonRules;
    }

    /**
     * 获取通用的规则
     * @return array
     */
    public function commonRules()
    {
        return [];
    }

    /**
     * 获取创建场景下的规则
     * @return array
     */
    public function createRules()
    {
        return [];
    }

    /**
     * 获取更新场景下的规则
     * @return array
     */
    public function updateRules()
    {
        return [];
    }

    /**
     * Get custom messages for validator errors.
     *
     * @return array
     */
    public function messages()
    {
        return property_exists($this, 'message') ? $this->message : $this->messages;
    }

    /**
     * Get custom attributes for validator errors.
     *
     * @return array
     */
    public function attributes()
    {
        return property_exists($this, 'field') ? $this->field : $this->fields;
    }

    /**
     * Handle a failed validation attempt.
     *
     * @param Validator $validator
     * @return void
     *
     * @throws \Illuminate\Validation\ValidationException
     */
    protected function failedValidation(Validator $validator): void
    {
        throw (new ValidationException($validator))
            ->errorBag($this->errorBag)
            ->redirectTo($this->getRedirectUrl());
    }

    /**
     * @param Validator $validator
     * @return void
     */
    protected function withValidator(Validator $validator)
    {
    }

    /**
     * 是否是创建场景
     * @return bool
     */
    protected function isCreateScene()
    {
        return $this->is('*/create');
    }

    /**
     * 是否是更新场景
     * @return bool
     */
    protected function isUpdateScene()
    {
        return $this->is('*/update');
    }

    /**
     * 获取其他的场景
     * @return string
     */
    protected function getScene()
    {
        // 获取路由名称
        $routeName = $this->route()->getName();

        if (strpos($routeName, '.')) {
            // 获取最后一个点后面的字符串
            $routeName = substr($routeName, strrpos($routeName, '.') + 1);
        }

        return $routeName;
    }
}
